/* 
 * Plugin to manage validation of forms
 */
(function($){
  $.fn.TWS_Form = function (inputOptions) {

    var arg = arguments[0];
    if (typeof arg === "string") {
      var func = methods["twsForm_" + arguments[0]];
      if (typeof func === "function") {
        if (!$(this).hasClass("tws-form")) {
          $.TWS_Console("warn", "TWS_Form object not created.  Not calling [%s] method.", arg);
          return false;
        } else {
          return func.apply(this, Array.prototype.slice.call(arguments,1));
        }
      } else {
        $.TWS_Console("warn", "TWS_Form: \"%s\" is not supported.", arg);
        return false;
      }
    } else { // Start of the constructor.
      if ($(this).hasClass("tws-form")) {
        $.TWS_Console("warn", "TWS_Form object already created on id [%s].", $(this).attr("id"));
        return this;
      }

      var defaults = {
        errorContainer: "",
        defaultFocus: false,
        enter: $.noop,
        rules: {},
        hiddenRules: {},
        messages: {}
      };
      var options = $.extend(defaults, inputOptions);
      
      //Applying masks
      $("[rel=time]", this).timeEntry({ampmPrefix: ' ', spinnerImage : false});
      $("[type=tel]", this).mask("(999) 999-9999"); //$("[type=tel]").mask("(999) 999-9999? x99999");
      $("[type=date], [rel=date]", this).mask("99/99/9999");

      //Error link setup
      $(".errorLink", this).live("click", function() {
        var field = $(this).attr("href");
        $(field).focus();
        return false;
      });

        /* For urls - put http:// when focusing on fields */
        $("[type=url]", this).focus(function(){
          var $elem = $(this);
          if(!$elem.val()){
            $elem.val("http://");
          }
        }).blur(function(){
          var $elem = $(this);
          if($elem.val()==="http://"){
            $elem.val("");
          }
        });

        //date picker
        $("[rel=date], type[date]", this).datepicker({showButtonPanel: true, changeMonth : true, changeYear : true, yearRange: '1900:c+10'}).attr("size","15");

        //setting up help
        if (options.validate && options.validate.rules){
          var helpIcon = '<span class="helpIcon"></span>';
          $.each(options.validate.rules, function(rule, detail){
            if(detail.help) {
              var $element = $("#"+ rule);
              var helpVal ="";
              var helpTitle = $element.prop("tagName").toLowerCase()==="fieldset" ? $element.find("legend").contents().filter(function() {return this.nodeType == 3;}).text() : $element.parent("label").contents().filter(function() {return this.nodeType == 3;}).text();
              helpTitle = $.trim(helpTitle);
              if (typeof detail.help === "string") {
                helpVal = helpTitle + "|" + detail.help ;
              } else if(typeof detail.help ==="object") {
                helpTitle = detail.help.title || helpTitle;
                helpVal = helpTitle + "|" + (detail.help.text || "");
              }
              helpIcon ="<span class='helpIcon' data-tws-help='"+helpVal+"'></span>";
              if ($element.prop("tagName").toLowerCase()==="fieldset") {
                $element.find("legend").prepend(helpIcon);
              } else {$element.parent("label").prepend(helpIcon);}
            }
          });
        }

        //cluetip
        $("[data-tws-help]", this).cluetip({titleAttribute : "data-tws-help", splitTitle: "|", arrows : true, leftOffset : 12, fx : {open : "fadeIn", openSpeed : 150}, cluetipClass: 'tws', cursor: 'pointer', dropShadow : false});

      return this.each(function() {
        var $form = $(this);
        //validation
        if(options.validate) {
          //errors
          var formErrors = options.validate.errorContainer || $form.attr("id") + "_formErrors";
          if(!options.validate.errorContainer) {
            $form.prepend("<div id='"+ formErrors + "'></div>");
          }
          var $formErrors = $("#" + formErrors);
          if(!$formErrors.hasClass("formErrors") ){$formErrors.addClass("formErrors")}
          if($formErrors.find("div.formErrorsHeader").size()===0) {$formErrors.append('<div class="formErrorsHeader">Please correct these errors:</div><ul></ul>').hide();}
          if($formErrors.find("ul").size()===0){$formErrors.append("<ul></ul>");}
          //setup error containers after form rows
          $("div.row", $form).each(function(){
            var $row = $(this);
            if($row.find("div.fieldErrors").size()===0){
              $row.append('<div class="fieldErrors"></div>');
            }
          });

          var defaultValidate = {
            errorLabelContainer : "#" + formErrors + " ul",
            wrapper : "li",
            onfocusout : false,
            onkeyup : false,
            onclick : false,
            showErrors: function(errorMap, errorList) {
              //cleanup
              $(".errorIcon", $form).remove();
              $("div.fieldErrors", $form).empty();
              if(!$.isEmptyObject(errorMap)){
                $("#" + formErrors, $form).show();
                $.each(errorMap, function(index, value){
                  var errorIcon = '<span class="errorIcon"></span>';
                  var $errorElement = $(value);
                  if ($errorElement.attr("rel")==="group") {
                    $("#" + index).find("legend").append(errorIcon);
                  } else {$("#" + index).before(errorIcon);}
                });
                //Add row errors
                $.each(errorList, function(ind, val){
                  $(val.element).parents("div.row").find("div.fieldErrors").append("<span>" + stripHtmlTags(val.message) + "</span>");
                });
              } else {$("#" + formErrors).hide();}
              this.defaultShowErrors();
            },
            debug : false
          };
          //Looking at rules and setting up default messages
          if(options.validate.rules){
            //storing validation rules
            $form.data("tws_validationRules",$.extend(true, {}, options.validate.rules));
            if (!options.validate.messages){options.validate.messages={};}
            var messages = $.extend(true, {} , options.validate.messages);
            $.each(options.validate.rules, function(index, value){
              var field = index;
              if(options.validate.rules[field].help){delete options.validate.rules[field].help;} //remove help fields
              $.each(value, function(ind, val){
                var messageText = "";
                if(!(messages[field] && messages[field][ind])) {
                  var errorLink = "";
                  if ($("#" + field)[0].tagName==="FIELDSET") {
                    errorLink = '<a href="#'+field +'" class="errorLink" rel="group" >' +stripHtmlTags($("#" + field).find("legend").contents().filter(function() {return this.nodeType == 3;}).text()).trim()+ '</a>';
                  } else {
                    errorLink = '<a href="#'+field +'" class="errorLink" >' +stripHtmlTags($("#" + field).parent("label").contents().filter(function() {return this.nodeType == 3;}).text()).trim()+ '</a>';
                  }
                  switch (ind) {
                    case "required" :
                      messageText =  errorLink +' is required.';
                      break;
                    case "minlength" :
                      messageText = errorLink + ' is invalid. It requires at least {0} characters.';
                      break;
                    case "maxlength" :
                      messageText = errorLink + ' is invalid. Maximum of {0} characters allowed.';
                      break;
                    case "lettersonly" :
                      messageText = errorLink + ' is invalid. It must contain letters only.';
                      break;
                    case "date" :
                      messageText = errorLink + ' is invalid. Valid date format is \'mm/dd/yyyy\'.';
                      break;
                    case "email" :
                      messageText = errorLink + ' is invalid. Please enter a valid email address.';
                      break;
                    case "zip" :
                      messageText = errorLink + ' is invalid. Valid zip format is xxxxx or xxxxx-xxxx.';
                      break;
                    case "requiredGroup" : //rel="group" has to be added to link
                      messageText = errorLink + ' is required.';
                      break;
                    case "phoneUS" :
                      messageText = errorLink + ' is invalid. Valid phone format is \'(123) 456-7890\'.';
                      break;
                    case "url" :
                      messageText = errorLink + ' is invalid. Please enter a valid url (web address).';
                      break;
                    case "alphanumeric" :
                      messageText = errorLink + ' is invalid. Please enter alphanumeric characters.';
                      break;
                    case "digits" :
                      messageText = errorLink + ' is invalid. Please enter a valid number.';
                      break;
                    case "min" :
                      messageText = errorLink + ' is invalid. Minimum value is {0}.';
                      break;
                    case "max" :
                      messageText = errorLink + ' is invalid. Maximum value is {0}.';
                      break;
                    case "number" :
                      messageText = errorLink + ' is invalid. Please enter a valid decimal number.';
                      break;
                    case "creditcard" :
                      messageText = errorLink + ' is invalid. Please enter a valid credit card number.';
                      break;
                    case "money" :
                      messageText = errorLink + ' is invalid. Please enter a valid amount.';
                      break;
                    case "timestamp" :
                      messageText = errorLink + 'is invalid. Valid time format is \'12:59 AM\' or \'12:59 PM\'.';
                      break;
                  }
                  if (!messages[field]) {messages[field]={};}
                  messages[field][ind] = messageText;
                }
              });
            });
            //create messages
            $.extend(options.validate.messages, messages);
            //adding on custom validation
            $.extend(defaultValidate, {rules : options.validate.rules, messages : options.validate.messages});
          }//end of check for rules
          $form.validate(defaultValidate); // setup form validation
        } //end of check for validate
        if (options.ajaxForm) {
          var formOptions = {};
          if (!$.isEmptyObject(options.ajaxForm)){
            formOptions= options.ajaxForm
          }
          $form.ajaxForm(formOptions);
        }

      });
    }
  }
  function stripHtmlTags(stringIn) {
    var retVal = "";
    if(stringIn) {
      retVal = stringIn.replace(/<\/?[^>]+>/gi, '');
    }
    return retVal;
  }
})(jQuery);


